QTextCodec: avoid read-past-buffer in codecForName()
authorDebian Qt/KDE Maintainers <debian-qt-kde@lists.debian.org>
Wed, 29 Jul 2026 08:26:16 +0000 (11:26 +0300)
committerDmitry Shachnev <mitya57@debian.org>
Wed, 29 Jul 2026 08:26:16 +0000 (11:26 +0300)
Origin: upstream, https://code.qt.io/cgit/qt/qt5compat.git/commit/?id=894079b4932dc878
Last-Update: 2026-07-26

The old code passed a QByteArray to a function taking const char*,
invoking QByteArray::operator const char*() implicitly.

The callee expects the argument to be NUL-terminated, but if the
QByteArray was created fromRawData(), that is not guaranteed.

In newer Qt versions we have nullTerminated(), but this needs to be
picked further back, so use a std::string to do the null-termination.

Gbp-Pq: Name CVE-2026-9499.diff

src/corelib/codecs/qtextcodec.cpp

index 06fd88da90cdeec982f9bd52ac8a16db4ae30f29..3a8063f313fc10f73bf17c5fe274f10987882db2 100644 (file)
@@ -543,6 +543,10 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name)
     if (name.isEmpty())
         return nullptr;
 
+    // ensure NUL-termination:
+    const std::string name0(name.data(), size_t(name.size()));
+    // (do it outside the critical section, even if we may not need it)
+
     const TextCodecsMutexLocker locker;
 
     QCoreGlobalData *globalData = QCoreGlobalData::instance();
@@ -559,14 +563,14 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name)
 
     for (TextCodecListConstIt it = globalData->allCodecs.constBegin(), cend = globalData->allCodecs.constEnd(); it != cend; ++it) {
         QTextCodec *cursor = *it;
-        if (qTextCodecNameMatch(cursor->name(), name)) {
+        if (qTextCodecNameMatch(cursor->name().constData(), name0.data())) {
             if (cache)
                 cache->insert(name, cursor);
             return cursor;
         }
         QList<QByteArray> aliases = cursor->aliases();
         for (ByteArrayListConstIt ait = aliases.constBegin(), acend = aliases.constEnd(); ait != acend; ++ait) {
-            if (qTextCodecNameMatch(*ait, name)) {
+            if (qTextCodecNameMatch(ait->constData(), name0.data())) {
                 cache->insert(name, cursor);
                 return cursor;
             }
@@ -575,7 +579,7 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name)
 
     return nullptr;
 #else
-    return QIcuCodec::codecForNameUnlocked(name);
+    return QIcuCodec::codecForNameUnlocked(name0.data());
 #endif
 }